package paleGoldenRod.client;


import java.util.ArrayList;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

public class ScroogleGame implements ClickListener {
	ArrayList addedLetters;
	Timer timer;
	Tile playerTiles[];
	Grid grid;
	int myScore=0;
	boolean yourTurn=true;
	RootPanel rootPanel;
	int playerCount=2;
	Tile tiles[][];
	int player;
	public ScroogleGame(RootPanel rootPanel, int player){
		if(player==1)
			yourTurn=false;
		this.player = player;
		this.rootPanel = rootPanel;
		timer = new Timer() {
			public void run() {
				updateFromServer();
			}
		};
		if(!yourTurn)
			timer.schedule(1000);
		addedLetters = new ArrayList();
		tiles = new Tile[10][10];
		for (int r = 0; r < 10; ++r) {
			for (int c = 0; c < 10; ++c) {
				tiles[r][c] = new Tile(r,c, this);
				tiles[r][c].setEnabled(true);
				//grid.setWidget(r, c, tiles[r][c].getWidget());
				rootPanel.get("slot"+r+""+c).add(tiles[r][c].getWidget());
			}
		}
		int numLetters=7;
		playerTiles = new Tile[numLetters];
		char letters[] = getLetters(numLetters);
		for(int i=0;i<numLetters;i++){
			playerTiles[i] = new Tile(-1,i,letters[i],this);
			playerTiles[i].setEnabled(true);
			rootPanel.get("hand"+i).add(playerTiles[i].getWidget());
		}
		Button b = new Button("Submit",this);
		b.setTitle("submit");
		rootPanel.get("submit").add(b);
		b = new Button("Clear",this);
		b.setTitle("clear");
		rootPanel.get("clear").add(b);
	}
	protected void updateFromServer() {
		System.out.println("tick" + yourTurn);
		if(!yourTurn){
			MessagingServiceAsync messagingService = getMessagingService();
			AsyncCallback callback = new AsyncCallback(){
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					System.out.println("Sent failed");
				}
				public void onSuccess(Object result) {
					System.out.println("Recieved some data!");
					if(result!=null){
						System.out.println("Recieved non-null data from server: "+result);
						processNewWord((ArrayList)result);
						yourTurn=true;
					}
					else
						timer.schedule(1000);
				}
			};
			messagingService.update(player, callback);
		}
	}
	protected void processNewWord(ArrayList word) {
		for(int i=0;i<word.size();i++){
			SmallTile t = (SmallTile)word.get(i);
			RootPanel box = rootPanel.get("slot"+t.row+""+t.col);
			tiles[t.row][t.col].setValue(selectedTile.tile.value);
			while(box.getWidgetCount()>0)
				box.remove(0);
			GWT.log("row:"+t.row+" col:"+t.col+" letter:"+t.letter, null);
			box.add(new Tile(t.row,t.col,t.letter,this).getWidget());
		}
	}
	private char[] getLetters(int num) {
		// TODO request from server to prevent cheating
		char letters[] = new char[num];
		for(int i=0;i<num;i++){
			letters[i]=(char) ('A'+Random.nextInt(26));
		}
		return letters;
	}
	public class Tile {
		public ScroogleGame parent;
		public char value;
		protected MyButton button;
		public int row, col;
		public Tile(int r, int c, ScroogleGame parent){
			this.parent = parent;
			row=r;
			col=c;
			value=0;
//			button = new MyButton("<center><img src='http://www.highforce.com/free_wallpaper/thumbs/tn_medium-gray-tile.jpg' width='20px' height='20px'/></center>", parent, this);
			button = new MyButton("<center>&nbsp</center>",parent, this);
			button.setTitle("button");
			button.setWidth("20px");
			button.setHeight("20px");
//			button.setEnabled(false);
			button.addClickListener(parent);
		}
		public Tile(int r, int c, char letter, ScroogleGame parent){
			this.parent = parent;
			row=r;
			col=c;
			value=letter;
			button = new MyButton("<center>"+value+"</center>", parent, this);
			button.setTitle("button");
			button.setWidth("20px");
			button.setHeight("20px");
//			button.setEnabled(false);
			button.addClickListener(parent);
		}
		public Widget getWidget(){
			return button;
		}
		public char getValue(){
			return value;
		}
		public void setValue(char letter){
			value=letter;
		}
		public void setEnabled(boolean en){
			button.setEnabled(en);
		}
	}	
	public class MyButton extends Button{
		public Tile tile;
		public MyButton(String str, ClickListener cl, Tile t){
			super(str,cl);
			this.tile=t;
		}
	}
	MyButton selectedTile;

	public void onClick(Widget sender) {
		GWT.log("test", null);
		if(yourTurn){
			if(sender.getTitle().equals("button")){
				MyButton b = (MyButton)sender;
				System.out.println("Clicked!");
				if(b.tile.row==-1){
					selectTile(b);
				}
				else{
					placeTile(b);
				}
			}
			else if(sender.getTitle().equals("submit")){
				if(isLegalMove()){
					MessagingServiceAsync messagingService = getMessagingService();
					AsyncCallback callback = new AsyncCallback(){
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub
							System.out.println("Sent failed");
						}
						public void onSuccess(Object result) {
							int data = ((Integer)result).intValue();
							addedLetters.clear();
							myScore+=data;
							updateScore();
							System.out.println("Sent tiles");
							yourTurn=false;
							timer.schedule(5000);
						}
					};
					String[] words = new String[2];
					int minR=10;
					int minC=10;
					for(int i=0;i<addedLetters.size();i++){
						SmallTile t =(SmallTile)addedLetters.get(i); 
						if(t.col<minC)
							minC=t.col;
						if(t.row<minR)
							minR=t.row;
					}
					words[0] = new String("");
					words[1] = new String("");
					System.out.println("Upper right corner of word starts at... "+minR+" "+minC);
					for(int i=minC;tiles[minR][i].value!=0;i++){
						System.out.print(tiles[minR][i].value);
						words[0]+=tiles[minR][i].value;
					}
					System.out.println();
					for(int i=minR;tiles[i][minC].value!=0;i++){
						System.out.print(tiles[minR][i].value);
						words[1]+=tiles[i][minC].value;
					}
					messagingService.endTurn(addedLetters, words, player,callback);
					for(int i=0;i<7;i++){
						if(playerTiles[i]==null){
							char c = getLetters(1)[0];
							playerTiles[i] = new Tile(-1,i,c,tiles[0][0].parent);
							playerTiles[i].setEnabled(true);
							rootPanel.get("hand"+i).add(playerTiles[i].getWidget());
						}
					}
				}
				else{

				}
			}
		}
	}
	protected void updateScore() {
		RootPanel score = rootPanel.get("score");
		while(score.getWidgetCount()>0)
			score.remove(0);
		score.add(new HTML("<h1>"+myScore+"</h1>"));
	}
	private MessagingServiceAsync getMessagingService(){
		MessagingServiceAsync messagingService = (MessagingServiceAsync) 
		GWT.create(MessagingService.class);
		ServiceDefTarget endpoint = (ServiceDefTarget) messagingService;
		String moduleRelativeUrl = GWT.getModuleBaseURL() + "messagingService";
		endpoint.setServiceEntryPoint(moduleRelativeUrl);
		return messagingService;
	}
	private boolean isLegalMove() {
		if(addedLetters.size()<1)
			return false;
		SmallTile t = (SmallTile)addedLetters.get(0);
		int row = t.row;
		int col = t.col;
		boolean validRow=true;
		boolean validCol=true;
		for(int i=1;i<addedLetters.size();i++){
			t = (SmallTile)addedLetters.get(i);
			if(t.row!=row){
				validRow=false;
			}
			if(t.col!=col){
				validCol=false;
			}
		}
		return validRow||validCol;
	}
	private void placeTile(MyButton b) {
		if(selectedTile!=null && b.tile.value==0){
			rootPanel.get("slot"+b.tile.row+""+b.tile.col).remove(0);
			rootPanel.get("slot"+b.tile.row+""+b.tile.col).add(new Tile(b.tile.row,b.tile.col,selectedTile.tile.value,b.tile.parent).getWidget());
			tiles[b.tile.row][b.tile.col].setValue(selectedTile.tile.value);
			SmallTile t = new SmallTile(b.tile.col,b.tile.row,selectedTile.tile.value);
			addedLetters.add(t);
			System.out.println("hand"+selectedTile.tile.col);
			if(rootPanel.get("hand"+selectedTile.tile.col).getWidgetCount()>0){
				playerTiles[selectedTile.tile.col]=null;
				System.out.println("contains widgets");
				rootPanel.get("hand"+selectedTile.tile.col).remove(0);
			}
			selectedTile=null;
		}
	}
	private void selectTile(MyButton b) {
		selectedTile=b;
	}

}